"""
用户管理模块 - API序列化器
"""
from rest_framework import serializers
from django.contrib.auth import authenticate
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError
from django.utils import timezone
from .models import User, StudentProfile, TeacherProfile, UserProfile


class UserProfileSerializer(serializers.ModelSerializer):
    """用户档案序列化器"""
    class Meta:
        model = UserProfile
        fields = ['avatar', 'bio', 'learning_progress', 'preferences', 'notifications']
        read_only_fields = ['learning_progress']


class StudentProfileSerializer(serializers.ModelSerializer):
    """学生档案序列化器"""
    class Meta:
        model = StudentProfile
        fields = [
            'student_id', 'class_name', 'grade', 'major',
            'enrollment_date', 'graduation_date', 'gpa', 'credits'
        ]


class TeacherProfileSerializer(serializers.ModelSerializer):
    """教师档案序列化器"""
    class Meta:
        model = TeacherProfile
        fields = [
            'teacher_id', 'department', 'title', 'specialization',
            'education', 'hire_date', 'office', 'research_interests',
            'publications'
        ]


class UserSerializer(serializers.ModelSerializer):
    """用户序列化器"""
    profile = UserProfileSerializer(read_only=True)
    student_profile = StudentProfileSerializer(read_only=True)
    teacher_profile = TeacherProfileSerializer(read_only=True)

    class Meta:
        model = User
        fields = [
            'id', 'username', 'email', 'real_name', 'role', 'phone',
            'avatar', 'is_active', 'is_verified', 'date_joined',
            'last_login', 'profile', 'student_profile', 'teacher_profile'
        ]
        read_only_fields = ['id', 'date_joined', 'last_login', 'is_verified']


class UserCreateSerializer(serializers.ModelSerializer):
    """用户创建序列化器"""
    password = serializers.CharField(
        write_only=True,
        validators=[validate_password],
        min_length=8,
        help_text="密码长度至少8位"
    )
    password_confirm = serializers.CharField(write_only=True, help_text="确认密码")

    class Meta:
        model = User
        fields = [
            'username', 'email', 'password', 'password_confirm',
            'real_name', 'role', 'phone'
        ]

    def validate_email(self, value):
        """验证邮箱唯一性"""
        if User.objects.filter(email=value).exists():
            raise serializers.ValidationError("该邮箱已被注册")
        return value

    def validate_username(self, value):
        """验证用户名唯一性"""
        if User.objects.filter(username=value).exists():
            raise serializers.ValidationError("该用户名已被使用")
        return value

    def validate(self, attrs):
        """验证密码确认"""
        if attrs['password'] != attrs['password_confirm']:
            raise serializers.ValidationError("两次输入的密码不一致")
        return attrs

    def create(self, validated_data):
        """创建用户"""
        validated_data.pop('password_confirm')
        password = validated_data.pop('password')

        user = User.objects.create_user(
            password=password,
            **validated_data
        )

        # 创建用户档案
        UserProfile.objects.create(user=user)

        # 根据角色创建对应档案
        if user.role == User.Role.STUDENT:
            StudentProfile.objects.create(
                user=user,
                student_id=f"STU{str(user.id).replace('-', '')[:10]}",
                enrollment_date=timezone.now().date()
            )
        elif user.role == User.Role.TEACHER:
            TeacherProfile.objects.create(
                user=user,
                teacher_id=f"TCH{str(user.id).replace('-', '')[:10]}",
                hire_date=timezone.now().date()
            )

        return user


class UserUpdateSerializer(serializers.ModelSerializer):
    """用户更新序列化器"""
    class Meta:
        model = User
        fields = ['real_name', 'phone', 'avatar']

    def validate_phone(self, value):
        """验证手机号格式"""
        if value and not value.isdigit():
            raise serializers.ValidationError("手机号必须是数字")
        return value


class PasswordChangeSerializer(serializers.Serializer):
    """密码修改序列化器"""
    old_password = serializers.CharField(required=True, help_text="旧密码")
    new_password = serializers.CharField(
        required=True,
        validators=[validate_password],
        min_length=8,
        help_text="新密码(至少8位)"
    )
    new_password_confirm = serializers.CharField(required=True, help_text="确认新密码")

    def validate(self, attrs):
        """验证密码修改"""
        if attrs['new_password'] != attrs['new_password_confirm']:
            raise serializers.ValidationError("两次输入的新密码不一致")
        return attrs

    def validate_old_password(self, value):
        """验证旧密码"""
        user = self.context['request'].user
        if not user.check_password(value):
            raise serializers.ValidationError("旧密码错误")
        return value


class LoginSerializer(serializers.Serializer):
    """登录序列化器"""
    username = serializers.CharField(help_text="用户名或邮箱")
    password = serializers.CharField(write_only=True, help_text="密码")
    remember_me = serializers.BooleanField(default=False, help_text="记住我")

    def validate(self, attrs):
        """验证登录信息"""
        username = attrs.get('username')
        password = attrs.get('password')

        if username and password:
            # 尝试用用户名登录
            user = authenticate(username=username, password=password)

            # 如果用户名失败，尝试用邮箱登录
            if user is None:
                try:
                    user_obj = User.objects.get(email=username)
                    user = authenticate(username=user_obj.username, password=password)
                except User.DoesNotExist:
                    pass

            if user:
                if not user.is_active:
                    raise serializers.ValidationError("用户账户已被禁用")

                attrs['user'] = user
                return attrs
            else:
                raise serializers.ValidationError("用户名或密码错误")
        else:
            raise serializers.ValidationError("用户名和密码都是必填的")

    def create(self, validated_data):
        """创建登录响应"""
        from rest_framework_simplejwt.tokens import RefreshToken

        user = validated_data['user']
        refresh = RefreshToken.for_user(user)

        # 记录登录尝试
        self._record_login_attempt(user, True)

        # 更新最后登录信息
        user.last_login = timezone.now()
        user.last_login_ip = self._get_client_ip()
        user.save(update_fields=['last_login', 'last_login_ip'])

        # 记录活动日志
        self._log_user_activity(user, 'LOGIN')

        return {
            'user': UserSerializer(user).data,
            'refresh': str(refresh),
            'access': str(refresh.access_token),
        }

    def _get_client_ip(self):
        """获取客户端IP"""
        request = self.context.get('request')
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip

    def _record_login_attempt(self, user, success):
        """记录登录尝试"""
        from .models import LoginAttempt

        ip_address = self._get_client_ip()
        user_agent = self.context.get('request').META.get('HTTP_USER_AGENT', '')

        LoginAttempt.objects.create(
            username=user.username,
            ip_address=ip_address,
            user_agent=user_agent,
            status=LoginAttempt.Status.SUCCESS if success else LoginAttempt.Status.FAILED
        )

    def _log_user_activity(self, user, action_type):
        """记录用户活动"""
        from .models import UserActivityLog

        ip_address = self._get_client_ip()
        user_agent = self.context.get('request').META.get('HTTP_USER_AGENT', '')

        UserActivityLog.objects.create(
            user=user,
            action_type=action_type,
            description=f"用户登录系统",
            ip_address=ip_address,
            user_agent=user_agent
        )


class PasswordResetSerializer(serializers.Serializer):
    """密码重置序列化器"""
    email = serializers.EmailField(help_text="注册邮箱")

    def validate_email(self, value):
        """验证邮箱是否存在"""
        if not User.objects.filter(email=value).exists():
            raise serializers.ValidationError("该邮箱未注册")
        return value


class PasswordResetConfirmSerializer(serializers.Serializer):
    """密码重置确认序列化器"""
    token = serializers.CharField(help_text="重置令牌")
    new_password = serializers.CharField(
        validators=[validate_password],
        min_length=8,
        help_text="新密码(至少8位)"
    )
    new_password_confirm = serializers.CharField(help_text="确认新密码")

    def validate(self, attrs):
        """验证密码确认"""
        if attrs['new_password'] != attrs['new_password_confirm']:
            raise serializers.ValidationError("两次输入的密码不一致")
        return attrs